package cn.iocoder.yudao.module.bpm.controller.admin.hr;

import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONObject;
import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.util.json.JsonUtils;
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
import cn.iocoder.yudao.module.bpm.api.task.BpmProcessInstanceApi;
import cn.iocoder.yudao.module.bpm.api.task.dto.BpmProcessInstanceCreateReqDTO;
import cn.iocoder.yudao.module.bpm.controller.admin.definition.vo.process.BpmProcessDefinitionRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.BpmOALeaveCreateReqVO;
import cn.iocoder.yudao.module.bpm.controller.admin.oa.vo.HrCreateReqVo;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.instance.BpmProcessInstanceRespVO;
import cn.iocoder.yudao.module.bpm.controller.admin.task.vo.task.BpmTaskApproveReqVO;
import cn.iocoder.yudao.module.bpm.convert.definition.BpmProcessDefinitionConvert;
import cn.iocoder.yudao.module.bpm.convert.task.BpmProcessInstanceConvert;
import cn.iocoder.yudao.module.bpm.dal.dataobject.definition.BpmProcessDefinitionInfoDO;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.candidate.strategy.BpmTaskCandidateStartUserSelectStrategy;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.BpmnModelUtils;
import cn.iocoder.yudao.module.bpm.framework.flowable.core.util.FlowableUtils;
import cn.iocoder.yudao.module.bpm.service.definition.BpmProcessDefinitionService;
import cn.iocoder.yudao.module.bpm.service.hr.ActiveHrService;
import cn.iocoder.yudao.module.bpm.service.oa.BpmOALeaveService;
import cn.iocoder.yudao.module.bpm.service.task.BpmProcessInstanceService;
import cn.iocoder.yudao.module.bpm.service.task.BpmTaskService;
import cn.iocoder.yudao.module.system.api.dept.dto.DeptRespDTO;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import com.alibaba.fastjson.JSON;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import liquibase.pro.packaged.S;
import org.checkerframework.checker.units.qual.A;
import org.flowable.bpmn.model.BpmnModel;
import org.flowable.bpmn.model.UserTask;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.ProcessDefinition;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.validation.Valid;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getLoginUserId;

/**
 * @Author: 雨同我
 * @Description:
 * @DateTime: 2024/8/15 14:51
 **/

@Tag(name = "管理后台 - Hr工作流申请")
@RestController
@RequestMapping("/bpm-common")
@Validated
public class HrBpmController {

    @Autowired
    private ActiveHrService activeHrService;
//    @Resource
//    private BpmProcessInstanceApi bpmProcessInstanceApi;
    @Resource
    private BpmProcessInstanceApi processInstanceApi;


    @Resource
    private BpmProcessDefinitionService processDefinitionService;
    @Resource
    private BpmProcessInstanceService processInstanceService;
    @Resource
    private BpmTaskService taskService;

    @Resource
    private BpmOALeaveService leaveService;

    @Resource
    private StringRedisTemplate stringRedisTemplate;



/**
 * @Description: 创建前，需要先获取发起人自选的节点id
 * getDefiniteAndSelectTask
 * @Author: 雨同我
 * @DateTime: 2024/8/27 11:18
 * @param: null:
 * @return:
*/
    @PostMapping("/create")
    @Operation(summary = "创建hr请求申请")
    @PermitAll
    public CommonResult<String> createLeave(@RequestBody HrCreateReqVo createReqVO) {

        // 1. 校验合同是否在审批
//        CrmContractDO contract = validateContractExists(id);
//        if (ObjUtil.notEqual(contract.getAuditStatus(), CrmAuditStatusEnum.DRAFT.getStatus())) {
//            throw exception(CONTRACT_SUBMIT_FAIL_NOT_DRAFT);
//        }
//        stringRedisTemplate.opsForValue().set("user", String.valueOf(createReqVO.getUserId()));
        System.out.println();
        System.out.println(JSON.toJSONString(createReqVO)+" "+createReqVO.getUserId());

        FlowableUtils.setAuthenticatedUserId(createReqVO.getUserId());

        // 2. 创建合同审批流程实例
//        String processInstanceId = bpmProcessInstanceApi.createProcessInstance(createReqVO.getUserId(), new BpmProcessInstanceCreateReqDTO()
//                .setProcessDefinitionKey(createReqVO.getKey()).setBusinessKey(String.valueOf(createReqVO.getServiceId()))
//                .setStartUserSelectAssignees(createReqVO.getStartUserSelectAssignees()));

        return CommonResult.success(leaveService.createCommonModel(createReqVO));
    }

/**
 * @Description: 流程定义，并获取发起人自选的节点id
 * @Author: 雨同我
 * @DateTime: 2024/8/27 11:26
 * @param: null:
 * @return:
*/

    @GetMapping("/getDefiniteAndSelectTask")
    @Operation(summary = "获得流程定义")
    @Parameter(name = "id", description = "流程编号", required = true, example = "1024")
    @Parameter(name = "key", description = "流程定义标识", required = true, example = "1024")
    public CommonResult<BpmProcessDefinitionRespVO> getProcessDefinition(@RequestParam(value = "id", required = false) String id, @RequestParam(value = "key", required = false) String key) {
        ProcessDefinition processDefinition = id != null ? processDefinitionService.getProcessDefinition(id)
                : processDefinitionService.getActiveProcessDefinition(key);
        if (processDefinition == null) {
            return success(null);
        }
        BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.getProcessDefinitionInfo(processDefinition.getId());
        BpmnModel bpmnModel = processDefinitionService.getProcessDefinitionBpmnModel(processDefinition.getId());
        List<UserTask> userTaskList = BpmTaskCandidateStartUserSelectStrategy.getStartUserSelectUserTaskList(bpmnModel);
        return success(BpmProcessDefinitionConvert.INSTANCE.buildProcessDefinition(
                processDefinition, null, processDefinitionInfo, null, null, bpmnModel, userTaskList));
    }

    /**
     * @Description: 获取实例的状态，task_id
     * @Author: 雨同我
     * @DateTime: 2024/8/27 11:28
     * @param: null:
     * @return:
    */

    @GetMapping("/getInstanceAndStatus")
    @Operation(summary = "获得指定流程实例", description = "在【流程详细】界面中，进行调用")
    @Parameter(name = "id", description = "流程实例id,task表里面的实例id", required = true)
    public CommonResult<BpmProcessInstanceRespVO> getProcessInstance(@RequestParam("id") String id) {
        HistoricProcessInstance processInstance = processInstanceService.getHistoricProcessInstance(id);
        if (processInstance == null) {
            return success(null);
        }

        // 拼接返回
        ProcessDefinition processDefinition = processDefinitionService.getProcessDefinition(
                processInstance.getProcessDefinitionId());
        BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.getProcessDefinitionInfo(
                processInstance.getProcessDefinitionId());
        String bpmnXml = BpmnModelUtils.getBpmnXml(
                processDefinitionService.getProcessDefinitionBpmnModel(processInstance.getProcessDefinitionId()));

//        AdminUserRespDTO startUser = adminUserApi.getUser(NumberUtils.parseLong(processInstance.getStartUserId()));
//        DeptRespDTO dept = null;
//        if (startUser != null && startUser.getDeptId() != null) {
//            dept = deptApi.getDept(startUser.getDeptId());
//        }
        AdminUserRespDTO startUser=null;
        DeptRespDTO dept = null;

        return success(BpmProcessInstanceConvert.INSTANCE.buildProcessInstance(processInstance,
                processDefinition, processDefinitionInfo, bpmnXml, startUser, dept));
    }



    @PostMapping("/queryTaskStatus")
    @Operation(summary = "创建hr请求申请")
    @PermitAll
    public CommonResult<BpmProcessInstanceRespVO> createLeave(@Valid  String taskId) {
        BpmProcessInstanceRespVO processInstance = activeHrService.getProcessInstance(taskId);
        return CommonResult.success(processInstance);
    }



    @GetMapping ("/get")
    @Operation(summary = "获得流程定义")
    @Parameter(name = "id", description = "流程编号", required = true, example = "1024")
    @Parameter(name = "key", description = "流程定义标识", required = true, example = "1024")
    public CommonResult<BpmProcessDefinitionRespVO> getCommonProcessDefinition(
            @RequestParam(value = "id", required = false) String id,
            @RequestParam(value = "key", required = false) String key) {
        ProcessDefinition processDefinition = id != null ? processDefinitionService.getProcessDefinition(id)
                : processDefinitionService.getActiveProcessDefinition(key);
        if (processDefinition == null) {
            return success(null);
        }
        BpmProcessDefinitionInfoDO processDefinitionInfo = processDefinitionService.getProcessDefinitionInfo(processDefinition.getId());
        BpmnModel bpmnModel = processDefinitionService.getProcessDefinitionBpmnModel(processDefinition.getId());
        List<UserTask> userTaskList = BpmTaskCandidateStartUserSelectStrategy.getStartUserSelectUserTaskList(bpmnModel);
        return success(BpmProcessDefinitionConvert.INSTANCE.buildProcessDefinition(
                processDefinition, null, processDefinitionInfo, null, null, bpmnModel, userTaskList));
    }




//    public static List<T> queryHrUserDataByUserId(String... userId) {
//        String urlGet = " http://10.16.3.59:8090/sys/user/getuserdata?id=" + userId;
//        String token = "";
//        HttpRequest httpRequest = HttpUtil.createGet(url)
//                .header("tenant-id", "1").contentType("application/json");
//        String response = httpRequest.execute().body();
//        List<SysUserData> userDataList = JsonUtils.parseObject(response, SysUserData.class);
//        return userDataList;
//    }


//    public static void main(String[] args) {
//        // GET请求示例
//        String getUrl = "http://example.com/api/get";
//        Map<String, String> getHeaders = Map.of(
//                "Header1", "Value1",
//                "Header2", "Value2"
//        );
//        JSONObject getResponse = HttpUtil.createRequest(getUrl, getHeaders);
//        System.out.println(getResponse);
//
//        // POST请求示例
//        String postUrl = "http://example.com/api/post";
//        JSONObject postBody = new JSONObject();
//        postBody.put("key1", "value1");
//        Map<String, String> postHeaders = Map.of(
//                "Content-Type", "application/json"
//        );
//        JSONObject postResponse = HttpUtil.sendPostRequest(postUrl, postBody, postHeaders);
//        System.out.println(postResponse);
//
//        // POST请求，请求体为JSON数组
//        JSONArray jsonArrayBody = new JSONArray();
//        jsonArrayBody.add(postBody);
//        JSONObject postArrayResponse = HttpUtil.sendPostRequestWithJsonArray(postUrl, jsonArrayBody, postHeaders);
//        System.out.println(postArrayResponse);
//    }




    /**
     * @Description: ==========================================按钮操作================
     * @Author: 雨同我
     * @DateTime: 2024/8/27 14:41
    */

    @PutMapping("/approve")
    @Operation(summary = "通过任务")
//    @PreAuthorize("@ss.hasPermission('bpm:task:update')")
    public CommonResult<Boolean> approveTask(@Valid @RequestBody BpmTaskApproveReqVO reqVO) {
//        TODO 获取当前用户信息
        taskService.approveTask(WebFrameworkUtils.getLoginUserId(), reqVO);
        return success(true);
    }


}
